import Router from '@koa/router'
import { omit } from 'lodash'
import { Op } from 'sequelize'
import { updateRuntimeConfigFromDB } from '../configs/runtimeConfig'
import Article from '../models/Article'
import ArticleComment from '../models/ArticleComment'
import BigModelConfig from '../models/BigModelConfig'
import KnowledgeBase from '../models/KnowledgeBase'
import KnowledgeBaseFile from '../models/KnowledgeBaseFile'
import SiteConfig from '../models/SiteConfig'
import TeachCase from '../models/TeachCase'
import TeachCaseComment from '../models/TeachCaseComment'
import User from '../models/User'
import { collectionNameModelConfigCache } from './knowledgeBase/vectorStore'
import { generateArticleSummary } from './chat/generateArticleSummary'
import Question from '../models/Question'
import UserAnswer from '../models/UserAnswer'

const modelsMap = {
    users: User,
    articles: Article,
    bigModelConfigs: BigModelConfig,
    siteConfigs: SiteConfig,
    teachCases: TeachCase,
    knowledgeBases: KnowledgeBase,
    knowledgeBaseFiles: KnowledgeBaseFile,
    articleComments: ArticleComment,
    teachCaseComments: TeachCaseComment,
    questions: Question,
    userAnswers: UserAnswer,
}

// 把前端的dbInclude参数换成sequelize的include参数
const getDbInclude = (dbInclude: any[]) => {
    return dbInclude.map((item) => {
        console.log(item)
        if (typeof item === 'string') {
            return {
                model: modelsMap[item as keyof typeof modelsMap],
            }
        }

        return {
            ...item,
            model: modelsMap[item.model as keyof typeof modelsMap],
        }
    })
}

export const getList: Router.Middleware = async (ctx) => {
    const { modelName } = ctx.params

    const model = modelsMap[modelName as keyof typeof modelsMap]

    if (!model) {
        ctx.body = { success: false, msg: '参数错误' }
        return
    }

    const { page = 1, pageSize = 10 } = ctx.request.body as {
        page: string
        pageSize: string
    }

    const query = omit(ctx.request.body, [
        'page',
        'pageSize',
        'password',
        'dbInclude',
        'attributes',
    ])
    const dbInclude = getDbInclude(ctx.request.body.dbInclude)

    // 选择属性
    const attributes: any = { exclude: ['password', 'deleteAt'] }
    if (ctx.request.body.attributes) {
        const bodyAttributes = ctx.request.body.attributes
        if (bodyAttributes.include) {
            attributes.include = bodyAttributes.include
        }
        if (bodyAttributes.exclude) {
            bodyAttributes.exclude.push('password', 'deleteAt')
            attributes.exclude = bodyAttributes.exclude
        }
    }

    const where: any = {}

    for (const key in query) {
        if (query[key]) {
            if (key === 'id' || key.includes('Id')) {
                where[key] = query[key]
                continue
            }
            where[key] = {
                [Op.like]: `%${query[key]}%`,
            }
        }
    }
    try {
        // @ts-ignore
        const list = await model.findAndCountAll({
            distinct: true,
            where,
            attributes,
            limit: +pageSize,
            offset: (+page - 1) * +pageSize,
            order: [['createdAt', 'DESC']],
            include: dbInclude,
        })
        ctx.body = { success: true, data: list }
    } catch (error) {
        console.log(error)
        ctx.body = { success: false, msg: '获取列表失败' }
    }
    // ctx.body = { success: false, msg: '获取列表失败' }
}
export const del: Router.Middleware = async (ctx) => {
    const { modelName, id } = ctx.params

    const model = modelsMap[modelName as keyof typeof modelsMap]

    if (!model || !id) {
        ctx.body = { success: false, msg: '参数错误' }
        return
    }

    try {
        // @ts-ignore
        const list = await model.destroy({
            where: { id },
        })
        ctx.body = { success: true, data: list }
    } catch (error) {
        ctx.body = { success: false, msg: '删除失败' }
    }
}
export const update: Router.Middleware = async (ctx) => {
    const { modelName, id } = ctx.params

    const model = modelsMap[modelName as keyof typeof modelsMap]

    if (!model) {
        ctx.body = { success: false, msg: '参数错误' }
        return
    }

    const data = ctx.request.body

    try {
        const newData = { ...data, id }
        // @ts-ignore
        const list = await model.update(newData, {
            where: { id },
        })
        if (modelName === 'siteConfigs') {
            updateRuntimeConfigFromDB()
        }
        if (modelName === 'bigModelConfigs' || modelName === 'knowledgeBases') {
            collectionNameModelConfigCache.clear()
        }
        ctx.body = { success: true, data: list }
    } catch (error) {
        console.log(error)
        ctx.body = { success: false, msg: '更新失败' }
    }
}
export const add: Router.Middleware = async (ctx) => {
    const { modelName } = ctx.params

    const model = modelsMap[modelName as keyof typeof modelsMap]

    if (!model) {
        ctx.body = { success: false, msg: '参数错误' }
        return
    }

    const data = ctx.request.body

    try {
        // @ts-ignore
        const list = await model.create(data)
        // 如果是添加文章，则生成文章摘要
        if (modelName === 'articles') {
            generateArticleSummary(data.content).then((aiSummary) => {
                Article.update(
                    {
                        aiSummary,
                    },
                    {
                        where: {
                            id: list.id,
                        },
                    }
                )
            })
        }
        ctx.body = { success: true, data: list }
    } catch (error) {
        console.log(error)
        ctx.body = { success: false, msg: '添加失败' }
    }
}

export const getDict: Router.Middleware = async (ctx) => {
    const { modelName } = ctx.params

    const model = modelsMap[modelName as keyof typeof modelsMap]

    if (!model) {
        ctx.body = { success: false, msg: '参数错误' }
        return
    }

    const { labelProp = 'id', valueProp = 'id' } = ctx.request.query as {
        labelProp?: string
        valueProp?: string
    }

    try {
        // @ts-ignore
        const list = await model.findAll({
            attributes: {
                include: [valueProp, labelProp],
                exclude: ['password', 'deleteAt'],
            },

            order: [['createdAt', 'DESC']],
        })
        const result = list.map((item) => {
            return {
                label: item.get(labelProp),
                value: item.get(valueProp),
            }
        })
        ctx.body = result
    } catch (error) {
        console.log(error)
        ctx.body = { success: false, msg: '获取列表失败' }
    }
    // ctx.body = { success: false, msg: '获取列表失败' }
}
